在开发大型项目,编写复杂业务逻辑时,我们就期望代码在运行到某个位置时能够暂停,这样方便我们定位问题和实时常看一些变量的值。

此刻我们就需要进行代码调试,以便于快速定位问题,提高开发效率。

接下来介绍几种 Node.js 的调试方式和调试技巧:

1 使用 VS Code 调试

我们先来一段用于调试的代码 debug.js,方便后续的展开。

ts // 声明一个数组并初始化 const myArray = [1, 2, 3, 4, 5] // 声明一个对象并初始化 const myObject = { name: 'Alice', age: 30, city: 'New York' } // 输出原始数组和对象 console.log('The original array is:', myArray) console.log('The original object is:', myObject) // 向数组中添加一个元素 myArray.push(6) // 更新对象中的一个属性 myObject.age = 31 // 输出修改后的数组和对象 console.log('The modified array is:', myArray) console.log('The modified object is:', myObject)

1.1 创建断点

先为代码添加 2 个断点 (点击数字旁边的空白区域就能完成添加),如下图所示。

1.2 调试运行

通过 VS Code 触发调试的方式有很多,下面介绍几个常用的。

1.2.1 快捷入口

F5 或者在右侧点击 运行和调试

在弹出框中选择 Node.js

1.2.2 调试终端

在新建终端位置有个 JavaScript调试终端选项,或者 运行和调试 面板处,

通过这个调试终端执行指令都会唤起 debug 模式。

1.2.3 npm 脚本

在日常开发中,运行项目一般都是通过执行 npm 脚本,

比如开发启动项目 npm run dev,构建项目 npm run build 等等。

package.json 内容如下。

json { "scripts": { "dev": "node debug-chrome.js", "build": "node debug-chrome.js" } }

可以通过上面的 js调试终端 运行进入调试,

也可以在编辑器中触发。

1.3 调试窗口介绍

在调试程序启动后,咱们可以看见有个黄色的箭头停在了第一个断点处,

在左侧可以看到 变量调用堆栈监视断点 等小窗口,

调试控制台里会展示 console 打印的信息,顶部还有一个 debug 控制条,

下面我们逐个介绍每个窗口的作用。

1.3.1 变量窗口

展示此时此刻所有变量的信息,包含局部和本地,可以手动展开详细查看每个变量的数据和结构。

同时还可以手动修改,直接双击要修改的变量,直接编辑即可,按 Enter(回车) 保存。

同时在编辑代码的区域,也可把鼠标悬浮上去,查看此时变量的信息。

1.3.2 监视窗口

这部分可以编写自定义的表达式

比如下面的例子,添加了查看数组 1,2 两项目的值与和。

当相关值变动时,表达试的值也会变动。

1.3.3 调试工具条

一共 6 个按钮,作用介绍如下。

① 继续执行

点击后会继续执行代码,直到发现下一个断点。

② 单步跳过

直接执行下一条语句,并跳过当前函数内部的所有语句。

如上图所示,不会执行 console.log 内部的逻辑,直接调到了下一个 console 语句,表现上像一行行的执行了,

可以和下面的单步调试对比一下。

③ 单步调试

执行下一条语句并进入当前函数内部继续调试,

从左下角的调用堆栈可以看出来,是进入了 console.log 函数内部执行。

2 使用 Chrome/Edge 调试

不习惯使用 VS Code 里操作调试的话也可以使用浏览器进行调试。

2.1 inspect-brk

在使用命令行执行脚本时添加一个参数 --inspect-brk

表示以调试模式启动并且在首行断住。

sh node --inspect-brk ./debug.js

可以看到终端里打印了一个 WebSocket 地址。

2.2 浏览器访问

此时使用 Chrome/Edge 访问 chrome://inspect 或者 edge://inspect 就能看到咱们 debug 的目标程序,

点击 inspect 就能看见和 VS Code 里类似的调试面板了,

同样的也是在左侧行号处添加断点,右侧包含与 VS Code 一样作用的 监视器断点变量调用堆栈 等面板。

当然断点也可以直接写在代码里,关键字为 debugger

咱们就用下面的代码来进行测试。

js // 声明一个名为 print 的函数,用于打印传入的值 function print(value) { debugger console.log('print', value) // 输出传入的值 } // 声明一个数组并初始化 const myArray = [1, 2, 3, 4, 5] // 声明一个对象并初始化 const myObject = { name: 'Alice', age: 30, city: 'New York' } debugger // 调用 print 函数,传入 myArray 作为参数,打印 myArray print(myArray) // 调用 print 函数,传入 myObject 作为参数,打印 myObject print(myObject)

下面是实操演示。

3 使用命令行调试

没有 IDE,没有 Chrome 能调试吗?当然能!!!

Node 内置了命令行中调试的指令,下面慢慢道来。

3.1 inspect 指令

inspect 是 Node.js 提供的一个命令行工具,具体用法如下:

sh node inspect debug-inspect.js

这里仍然使用上面的代码进行调试演示,debugger 同样生效。

js // 声明一个名为 print 的函数,用于打印传入的值 function print(value) { debugger console.log('print', value) // 输出传入的值 } // 声明一个数组并初始化 const myArray = [1, 2, 3, 4, 5] // 声明一个对象并初始化 const myObject = { name: 'Alice', age: 30, city: 'New York' } debugger // 调用 print 函数,传入 myArray 作为参数,打印 myArray print(myArray) // 调用 print 函数,传入 myObject 作为参数,打印 myObject print(myObject)

3.2 调试指令介绍

下面是一些常用的指令

| 指令 | 功能 | | -------------------- | --------------------------------------------------------------------------------------------------- | | sbsetBreakpoint | 在代码中的任何位置设置断点。可以使用 sb(10) 在第 10 行设置断点; sb('filename.js', 10)filename.js 文件的第 10 行设置断点 | | ccont | 继续执行程序,直到碰到下一个断点或者程序结束 | | nnext | 跳过当前行,执行下一行,并停在下一行 | | sstep | 进入当前行调用的函数,如果当前行没有函数调用,则执行下一行,并停在下一行 | | oout | 跳出当前函数,到调用当前函数的函数处,并停在该函数的下一行 | | repl | 进入 REPL 模式。在该模式下,你可以查看变量的值,运行任何表达式,甚至修改变量的值,而不需要停止程序运行 | | watch | 观察变量的值的改变。例如, watch('myArray') 将观察 myArray 变量的值的改变,每当它的值改变时,调试器都会记录下来。 |

当然还提供了许多其他的指令,例如 list(打印当前执行到的代码)backtrace(调用堆栈信息) 等等。你可以在调试过程中随时输入 help 来查看所有可用的指令。

下面演示一下常用指令的用法。

3.2.1 设置断点

除了使用 debugger 设置断点也可以在运行时使用 sb 设置,操作如下。

3.2.2 向下执行

使用 cnso 均可执行,具体效果如上面阐述那样,和 VS Code 里的调试工具调按钮作用一一对应。

3.2.3 查看执行代码

使用 list 方法,list() 显示当前执行到的位置,list(12) 显示第 12 行的代码。

3.2.4 重启

使用 r

3.2.5 监视器

watch 设置监视器,watchers 查看所有监视器的情况。

3.2.6 调用栈

使用 bt

小结

本节主要介绍了 3 种 Node.js 的调试方法,前两种图形化调试方法,是最常用的,命令行调试方法了解即可 (在某些没有 UI 的场合能够用上),

期望大家能够掌握这些常用的调试技巧和方法,提高开发效率。